<?php
/**
 * @package lib.famteam.phporm
 */
/**
 * @package lib.famteam.phporm
 * @author polikeiji
 *
 */
class Query {
	private $_tableName;
	private $_createTableQuery;
	private $_whereQuery;
	private $_orderBy;
	private $_groupBy;
	private $_limit;
	private $_distinct;
	private $_updateSetQuery;
	private $_insertColumnQuery;
	private $_insertValueQuery;
	private $_insertValueQueries;
	private $_selectLockMode;

	public function Query($tableName) {
		$this->_tableName = $tableName;
		$this->_createTableQuery = "";
		$this->_whereQuery = null;
		$this->_orderBy = "";
		$this->_limit = "";
		$this->_distinct = "";
		$this->_groupBy = "";
		$this->_updateSetQuery = "";
		$this->_insertColumnQuery = "";
		$this->_insertValueQuery = "";
		$this->_insertValueQueries = array();
		$this->_selectLockMode = '';
	}
	
	public function getTargetObject() {
		return $this->targetObject;
	}
	
	public function addColumn($columnName, $createDifinition) {
		if ($this->_createTableQuery != "") {
			$this->_createTableQuery .= ", ";
		}
		$this->_createTableQuery .= $columnName;
		$this->_createTableQuery .= " ";
		$this->_createTableQuery .= $createDifinition;
	}
	public function setWhereQuery($whereQuery) {
		$this->_whereQuery = $whereQuery;
	}
	public function setDistinct() {
		$this->_distinct = ' distinct';
	}
	public function setOrderBy($columnName) {
		$this->_orderBy = $columnName;
	}
	public function setGroupBy($columnName) {
		$this->_groupBy = $columnName;
	}
	public function setLimit($limit, $offset = 0) {
		$this->_limit = $offset . ', ' . $limit;
	}
	public function addUpdateValue($columnName, $value) {
		if (isset($columnName) && isset($value)) {
			if ($this->_updateSetQuery != "") {
				$this->_updateSetQuery .= ", ";
			}
			$this->_updateSetQuery .= $columnName;
			$this->_updateSetQuery .= "=";
			$this->_updateSetQuery .= $value;
		}
	}
	public function addUpdateFormula($formula) {
		if ($this->_updateSetQuery != "") {
			$this->_updateSetQuery .= ", ";
		}
		$this->_updateSetQuery .= $formula;
	}
	public function addInsertColumn($columnName) {
		if (isset($columnName)) {
			if ($this->_insertColumnQuery != "") {
				$this->_insertColumnQuery .= ", ";
			}
			$this->_insertColumnQuery .= $columnName;
		}
	}
	public function addInsertValue($value) {
		if (isset($value)) {
			if ($this->_insertValueQuery != "") {
				$this->_insertValueQuery .= ", ";
			}
			$this->_insertValueQuery .= ($value == null && $value !== 0 ? 'null' : $value);
		}
	}
	public function flushInsertValue() {
		$this->_insertValueQueries[] = $this->_insertValueQuery;
		$this->_insertValueQuery = "";
	}
	public function isForUpdate() {
		$this->_selectLockMode = 'for update';
	}
	public function haveWhereQuery() {
		$where = $this->_whereQuery;
		return isset($where) && $where->isNotEmptyQuery();
	}
	public function getCreateTableQuery() {
		$createTableQuery = 'create table if not exists ';
		$createTableQuery .= $this->_tableName;
		$createTableQuery .= ' (';
		$createTableQuery .= $this->_createTableQuery;
		$createTableQuery .= ')';
		return $createTableQuery;
	}
	public function getSelectQuery($connection) {
		$selectQuery = 'select';
		if ($this->_distinct != '') {
			$selectQuery .= $this->_distinct;
		}
		$selectQuery .= ' * from ';
		$selectQuery .= $this->_tableName;
		if ($this->haveWhereQuery()) {
			$selectQuery .= ' where ';
			$selectQuery .= $this->getWhereQuery($connection);
		}
		if ($this->_groupBy != "") {
			$selectQuery .= ' group by ';
			$selectQuery .= $this->_groupBy;
		}
		if ($this->_orderBy != "") {
			$selectQuery .= ' order by ';
			$selectQuery .= $this->_orderBy;
		}
		if ($this->_limit != "") {
			$selectQuery .= ' limit ';
			$selectQuery .= $this->_limit;
		}
		if ($this->_selectLockMode != '') {
			$selectQuery .= (' ' . $this->_selectLockMode);
		}
		return $selectQuery;
	}
	public function getCountSelectQuery($connection) {
		$countSelectQuery = 'select count(*) from ';
		$countSelectQuery .= $this->_tableName;
		if ($this->haveWhereQuery()) {
			$countSelectQuery .= ' where ';
			$countSelectQuery .= $this->getWhereQuery($connection);
		}
		return $countSelectQuery;
	}
	public function getMaxSelectQuery($columnName, $connection) {
		$countSelectQuery = 'select max(' . $columnName . ') from ';
		$countSelectQuery .= $this->_tableName;
		if ($this->haveWhereQuery()) {
			$countSelectQuery .= ' where ';
			$countSelectQuery .= $this->getWhereQuery($connection);
		}
		return $countSelectQuery;
	}
	public function getMinSelectQuery($columnName, $connection) {
		$countSelectQuery = 'select min(' . $columnName . ') from ';
		$countSelectQuery .= $this->_tableName;
		if ($this->haveWhereQuery()) {
			$countSelectQuery .= ' where ';
			$countSelectQuery .= $this->getWhereQuery($connection);
		}
		return $countSelectQuery;
	}
	public function getInsertQuery($ignore = false) {
		$insertQuery = 'insert ' . ($ignore ? 'ignore ' : '') . 'into ';
		$insertQuery .= $this->_tableName;
		$insertQuery .= ' (';
		$insertQuery .= $this->_insertColumnQuery;
		$insertQuery .= ') values (';
		$insertQuery .= implode('),(', $this->_insertValueQueries);
		$insertQuery .= ')';
		return $insertQuery;
	}
	public function getUpdateQuery($connection) {
		$updateQuery = 'update ';
		$updateQuery .= $this->_tableName;
		$updateQuery .= ' set ';
		$updateQuery .= $this->_updateSetQuery;
		if ($this->haveWhereQuery()) {
			$updateQuery .= ' where ';
			$updateQuery .= $this->getWhereQuery($connection);
		}
		return $updateQuery;
	}
	public function getDeleteQuery($connection) {
		$deleteQuery = 'delete from ';
		$deleteQuery .= $this->_tableName;
		if ($this->haveWhereQuery()) {
			$deleteQuery .= ' where ';
			$deleteQuery .= $this->getWhereQuery($connection);
		}
		return $deleteQuery;
	}
	public static function getQueryStringValue($value, $connection) {
		Logger::sqlLog('Before of escaping: ' . $value);
		$value = $connection != null ? mysql_real_escape_string($value, $connection) : $value;
		Logger::sqlLog('After of escaping: ' . $value);
		return "'" . $value . "'";
	}
	public static function getDateString($timestamp) {
		if ($timestamp != null) {
			return Query::getQueryStringValue(date('Y-m-d H:i:s', $timestamp), null);
		}
		else {
			return Query::getQueryStringValue('0000-00-00 00:00:00', null);
		}
	}
	public function getWhereQuery($connection) {
		$queryWhere = $this->_whereQuery;
		return $queryWhere->getWhereQuery($connection);
	}
}
?>
